5. K8S之Pod(2)-生命周期
如图
init容器
Pod 能够具有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的 Init 容器。
Init 容器与普通的容器非常像,除了如下两点:
- Init 容器总是运行到成功完成为止。
- 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成。(串行)
如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy
为 Never,它不会重新启动。
Pod phasePod的相位
Pod 的 status
在信息保存在 PodStatus 中定义,其中有一个 phase
字段。
Pod 的相位(phase)是 Pod 在其生命周期中的简单宏观概述。该阶段并不是对容器或 Pod 的综合汇总,也不是为了做为综合状态机。
Pod 相位的数量和含义是严格指定的。除了本文档中列举的状态外,不应该再假定 Pod 有其他的 phase
值。
下面是 phase
可能的值:
- 挂起(Pending):API Server创建了Pod资源对象并已经存入了etcd中,但是它并未被调度完成,或者仍然处于从仓库下载镜像的过程中。
- 运行中(Running):Pod已经被调度到某节点之上,并且所有容器都已经被kubelet创建完成。
- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
下图是Pod的生命周期示意图,从图中可以看到Pod状态的变化。
K8S Pod status的状态分析
1 | CrashLoopBackOff: 容器退出,kubelet正在将它重启 |
Pod健康检查 (存活性探测)
Pod启动后的健康状态可以由两类探针来检测:Liveness Probe(存活性探测) 和 Readiness Probe(就绪性探测)。如下图:
1. Readiness Probe
1. 用于判断容器是否启动完成(read状态),可以接受请求。容器虽然起来了,但是里面的服务启动还是需要一会儿的
2. 如果ReadnessProbe探针检测失败,则Pod的状态将被修改。Endpoint Controller将从Service的Endpoint中删除包含该容器所在Pod的Endpoint。
readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。Kubelet使用readiness probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当Pod中的容器都处于就绪状态时kubelet才会认定该Pod处于就绪状态。该信号的作用是控制哪些Pod应该作为service的后端。如果Pod处于非就绪状态,那么它们将会被从service的load balancer中移除。
2. Liveness Probe
1. 用于判断容器是否存活(running状态)。
2. 如果LivenessProbe探针探测到容器非健康,则kubelet将杀掉该容器,并根据容器的重启策略
做相应处理。
3. 如果容器不包含LivenessProbe探针,则kubelet认为该探针的返回值永远为“success”。
livenessProbe
:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。Kubelet使用liveness probe(存活探针)来确定何时重启容器。
Kubelet 可以选择是否执行在容器上运行的两种探针执行和做出反应,每次探测都将获得以下三种结果之一:
成功:容器通过了诊断。
失败:容器未通过诊断。
未知:诊断失败,因此不会采取任何行动。
探针是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的Handler。其存活性探测的方法有以下三种:
- ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
- TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
- HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
拿LivenessProbe
来举例:
- ExecAction:
1 | apiVersion: v1 |
- TCPSocketAction
1 | apiVersion: v1 |
- HTTPGetAction
1 | apiVersion: v1 |
ReadnessProbe 同理
配置Probe
Probe中有很多精确和详细的配置,通过它们你能准确的控制liveness和readiness检查:initialDelaySeconds
:容器启动后第一次执行探测是需要等待多少秒。即启动容器后首次进行健康检查的等待时间,单位为秒。periodSeconds
:执行探测的频率。默认是10秒,最小1秒。timeoutSeconds
:探测超时时间。默认1秒,最小1秒。即健康检查发送请求后等待响应的时间,如果超时响应kubelet则认为容器非健康,重启该容器,单位为秒。successThreshold
:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。failureThreshold
:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。
等等。。。
具体还是自己查查。。。
对于HTTP探测器,kubelet向指定的路径和端口发送HTTP请求以执行检查。 Kubelet将probe发送到容器的IP地址,除非地址被httpGet中的可选host字段覆盖。 在大多数情况下,不想设置主机字段。 有一种情况下可以设置它, 假设容器在127.0.0.1上侦听,并且Pod的hostNetwork字段为true。 然后,在httpGet下的host应该设置为127.0.0.1。 如果你的pod依赖于虚拟主机,这可能是更常见的情况,你不应该是用host,而是应该在httpHeaders中设置Host头。
Liveness Probe和Readiness Probe使用场景
- 如果容器中的进程能够在遇到问题或不健康的情况下自行崩溃,则不一定需要存活探针; kubelet 将根据 Pod 的restartPolicy 自动执行正确的操作。
- 如果希望容器在探测失败时被杀死并重新启动,那么请指定一个存活探针,并指定restartPolicy 为 Always 或 OnFailure。
- 如果要仅在探测成功时才开始向 Pod 发送流量,请指定就绪探针。在这种情况下,就绪探针可能与存活探针相同,但是 spec 中的就绪探针的存在意味着 Pod 将在没有接收到任何
- 流量的情况下启动,并且只有在探针探测成功后才开始接收流量。
- 如果你希望容器能够自行维护,您可以指定一个就绪探针,该探针检查与存活探针不同的端点。
说明: 请注意,如果你只是想在 Pod 被删除时能够排空请求,则不一定需要使用就绪态探针; 在删除 Pod 时,Pod 会自动将自身置于未就绪状态,无论就绪态探针是否存在。 等待 Pod 中的容器停止期间,Pod 会一直处于未就绪状态。
Pod生命周期中的另外一种行为lifecycle:启动后钩子和终止前钩子
在主容器刚刚启动之后,用户可以手动嵌入做一些操作,可以做一个 post start,比如执行完一个命令就退出。
如果主容器要退出,在结束之前,也可以做一些事情,pre stop。类似于awk的BEGIN和END。
Kubernetes 为我们提供了两种钩子函数:
- PostStart:这个钩子在容器创建后立即执行。但是,并不能保证钩子将在容器
ENTRYPOINT
之前运行,因为没有参数传递给处理程序。主要用于资源部署、环境准备等。不过需要注意的是如果钩子花费太长时间以至于不能运行或者挂起, 容器将不能达到running
状态。 - PreStop:这个钩子在容器终止之前立即被调用。它是阻塞的,意味着它是同步的, 所以它必须在删除容器的调用发出之前完成。主要用于优雅关闭应用程序、通知其他系统等。如果钩子在执行期间挂起, Pod阶段将停留在
running
状态并且永不会达到failed
状态。